/*
  Display Driver for Grafic Display Module DEM128064A.

  IMPORTANT: The functions DisplayRead() and WaitBusy()
             are not working. The BUSY bit always reads as 1.
             However, it is not neccesary to wait for the busy flag.
             The driver will be improved later.

  Author: Henning Hargaard
  Date: 5.2.2008
 */

#include <avr/io.h>
#include <util/delay.h>
#include "DEM128064A.h"



// LOCAL FUNCTIONS /////////////////////////////////////////////////////////////

// Writes a byte to the display
void DisplayWrite(unsigned char chip, unsigned char data, unsigned char Type)
{
	if(Type == 0)
		CONTROL_PORT &= ~(1<<LCD_RS); //Set register select to instruction
	else
		CONTROL_PORT |= (1<<LCD_RS); //Set register select to data

	CONTROL_PORT &= ~(1<<LCD_E);  //lcd 'E' pin low
	_delay_us(3);

	CONTROL_PORT &= ~(1<<LCD_RW); //Set r/w pin to write

	if(chip == 0)
		enable_cs1();
	else
		enable_cs2();

	_delay_us(3);

	DATA_OUT = data;
	eStrobe();
}

// Reads a byte from the display
unsigned char DisplayRead(unsigned char Chip, unsigned char Type)
{

	return 0;
}

// Set the display Y address counter 0-63 (left or right chip)
void SetY(unsigned char Chip, unsigned char Y)
{
	CONTROL_PORT &= ~(1<<LCD_RW); //Set r/w pin to write
	CONTROL_PORT &= ~(1<<LCD_RS); //Set register select to instruction

	unsigned char data = 0b01000000 | Y;
	if(Chip == 0)
		enable_cs1();
	else
		enable_cs2();

	DATA_OUT = Y;
	eStrobe();

}

// Set the display page number 0-7 (left or right chip)
void SetPage(unsigned char Chip, unsigned char Page)
{
	CONTROL_PORT &= ~(1<<LCD_RW); //Set r/w pin to write
	CONTROL_PORT &= ~(1<<LCD_RS); //Set register select to instruction

	unsigned char data = 0b10111000 | Page;
	if(Chip == 0)
		enable_cs1();
	else
		enable_cs2();

	DATA_OUT = data;
	eStrobe();
}

// Clears all pixels at one of the half screens (left or right)
void ClearHalfScreen(unsigned char Chip)
{
}

//====================================================================
//
//====================================================================
void eStrobe (void)
{
	CONTROL_PORT |= (1<<LCD_E);   //lcd 'E' pin high
	_delay_us(3);
	CONTROL_PORT &= ~(1<<LCD_E);  //lcd 'E' pin low
	_delay_us(3);
}

//====================================================================
//====================================================================
//
//====================================================================
void enable_cs1 (void)
{
	CONTROL_PORT |= (1<<LCD_CS1);   //Enable the CS1 of the display
	CONTROL_PORT &= ~(1<<LCD_CS2);   //Disable the CS2 of the display
}

//====================================================================
//
//====================================================================
void enable_cs2 (void)
{
	CONTROL_PORT |= (1<<LCD_CS2);   //Enable the CS2 of the display
	CONTROL_PORT &= ~(1<<LCD_CS1);   //Disable the CS1 of the display
}

//====================================================================
//
//====================================================================
void disable_cs (void)
{
	CONTROL_PORT &= ~(1<<LCD_CS1);   //Disable the CS1 of the display
	CONTROL_PORT &= ~(1<<LCD_CS2);   //Disable the CS2 of the display
}
// PUBLIC FUNCTIONS ////////////////////////////////////////////////////////////

// Initializes (resets) the display and sets up the initial control signals
void DisplayInit()
{
	unsigned char dataY = 0b01111111;
	unsigned char dataPage = 0b10111111;

	DATA_IN = 0;  //DATA Port Low
	DATA_DDR = 0xff; //Make DATA port output

	CONTROL_PORT = 0;   //CONTROL Port Low
	CONTROL_DDR = 0xff; //Make CONTROL port outputs

	CONTROL_PORT &= ~(1<<LCD_E);
	CONTROL_PORT &= ~(1<<LCD_CS1);   //disable the CS1 of the display
	CONTROL_PORT &= ~(1<<LCD_CS2);   //Disable the CS2 of the display
	CONTROL_PORT &= ~(1<<LCD_RS);   //Clear RS  \_
	CONTROL_PORT &= ~(1<<LCD_RW);   //Clear RW  /  Command mode

	CONTROL_PORT &= ~(1<<LCD_RSTB);
	_delay_ms(200);
	CONTROL_PORT |= (1<<LCD_RSTB);

	CONTROL_PORT &= ~(1<<LCD_RW); //Set r/w pin to write
	CONTROL_PORT &= ~(1<<LCD_RS); //Set register select to instruction
	CONTROL_PORT |= (1<<LCD_CS1);   //Enable the CS1 of the display
	CONTROL_PORT &= ~(1<<LCD_CS2);   //Disable the CS2 of the display
	DATA_OUT = 0b01000000;
	CONTROL_PORT |= (1<<LCD_E);   //lcd 'E' pin high
	_delay_us(3);
	CONTROL_PORT &= ~(1<<LCD_E);  //lcd 'E' pin low
	_delay_us(3);

	DATA_OUT = 0b10111000;
	CONTROL_PORT |= (1<<LCD_E);   //lcd 'E' pin high
	_delay_us(3);
	CONTROL_PORT &= ~(1<<LCD_E);  //lcd 'E' pin low
	_delay_us(3);

	CONTROL_PORT |= (1<<LCD_RS); //Set register select to data

	CONTROL_PORT &= ~(1<<LCD_E);  //lcd 'E' pin low
	_delay_us(3);

	CONTROL_PORT &= ~(1<<LCD_RW); //Set r/w pin to write

	_delay_us(3);

	DATA_OUT = 0x0F;
	CONTROL_PORT |= (1<<LCD_E);   //lcd 'E' pin high
	_delay_us(3);
	CONTROL_PORT &= ~(1<<LCD_E);  //lcd 'E' pin low
	_delay_us(3);


}

// Turns the display (both left and right side) on
void DisplayOn()
{

	DisplayWrite(0,0b00111111,0);

}

// Turns the display (both left and right side) off
void DisplayOff()
{

}

// Clears all pixels at the whole screen (left and right)
void ClearScreen()
{

}

// Sets one pixel at x,y
// Notice: x = Horizontal (0-127), y = Vertical (0-63)
// This correspons to the "logical" x and y terms
// in contrast to the display internal definitions
void SetPixel(unsigned char x, unsigned char y)
{

	DATA_OUT = 0b11000000 | y;   //Display start line = 0 (0-63)
	eStrobe();

	if(x>64)
	{
		SetY(0,x);
	}
	else
	{
		SetY(1,x-64);
	}


}

// Displays a graphical image (whole screen)
// The parameter is a pointer to the bit array defining the image
void DisplayPic(char *picArray)
{
}


// Draws one horizontal line
// "StartX, StartY" is the (logical) start position of the line
// "Length" is the line length in pixels
void Draw_Horizontal_Line(unsigned char StartX, unsigned char StartY, unsigned char Length)
{
}


